﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;


namespace Oiler
{
    public class MapControl
    {
        public Vector2 MapPosition;
        public Vector2 velocity;
        public Texture2D Map;
        public Texture2D dotTexture;
        
        public Vector2[] depositPos;

        public float mapScale;
        public bool isDragging;
        public bool canMove;
        
        #region INITIALIZE     
        public void Initialize(Texture2D texture, Texture2D textureDot)
        {
            //intializes the map texture
            Map = texture;

            //initializes the oil deposite texture
            dotTexture = textureDot;

            //sets the mapscale to it starting position of .5 at every start up
            mapScale = .5f;

            //sets map texture position to starting position of 80,50 at every start up
            MapPosition = new Vector2(80, 50);

            //creates an array for the oil deposite texture positions
            //later to be declared in the update method for update reasoning
            depositPos = new Vector2[3];
        }
        #endregion

        #region UPDATE
        public void Update(GameTimerEventArgs time)
        {
            //basic touch handleing for windows phone touch panel
            HandleTouch();

            //moves map texture based on a scaled velocity which is set
            //by a flick motion in the HandleTouch method
            MapPosition += velocity * .1f;

            //moves deposit textures based on the same value that moves 
            //the map texture
            for(int i = 0; i < depositPos.Length; i++)
            {
                depositPos[i] += velocity * .1f;
            }

            //decays velocity overtime
            velocity *= 1f - .1f;

            //keeps the map drawing outside of map texture boundries
            //while providing a 100 pixels of coushion for a better feel
            MapRestrictions(MapPosition.X + 100, MapPosition.Y + 100);
            MapRestrictions(-Map.Width * mapScale + 700, -Map.Height * mapScale + 380);
            
            //restricts the camera from zooming to far in or out
            if(mapScale <= .5f)
            {
                mapScale = .5f;
            }
            if (mapScale >= 2f)
            {
                mapScale = 2f;
            }

            //sets the velocity of the map texture to 0 if the map boundries are meet
            if (MapPosition.X > 80 || 800 - (Map.Width * mapScale) > MapPosition.X)
            {
                velocity.X = 0;
            }
            if(MapPosition.Y > 50|| 480 - (Map.Height * mapScale) > MapPosition.Y)
            {
                velocity.Y = 0;
            }

            /*
             * 0 = Alaska
             * 1 = Gulf Coast
             * 2 = Middle East
             */
            //Sets the deposite dot texture to its respected position
            //also moves it based on the map texture position
            depositPos[0] = new Vector2(80 * mapScale + MapPosition.X, 50 * mapScale + MapPosition.Y);
            depositPos[1] = new Vector2(185 * mapScale + MapPosition.X, 310 * mapScale + MapPosition.Y);
            depositPos[2] = new Vector2(740 * mapScale + MapPosition.X, 255 * mapScale + MapPosition.Y);
        }
        #endregion
        
        #region DRAW
        public void Draw(SpriteBatch spriteBatch, SpriteFont GameFont)
        {
            //Draws the map and its map position
            spriteBatch.Draw(Map, MapPosition, null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale, SpriteEffects.None, 0f);

            //Runs through an Array holding the position of every
            //oil deposit while placing, and updating the position of
            //where the deposit texture will sit
            for (int i = 0; i < depositPos.Length; i++)
            {
                spriteBatch.Draw(dotTexture, depositPos[i], null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale / 1.5f, SpriteEffects.None, 0f);
            }

            //If the beginning of the map texture is south of the GUI (.Y = 50),
            //and the user is no longer dragging the map.
            if (MapPosition.Y > 50 && isDragging == false)
            {
                //Then the map is drawn -20 pixels on the y axis from
                //its position since the first loop. This will continuously
                //happen until the map is aligned with the GUI.
                spriteBatch.Draw(Map, MapPosition = new Vector2(MapPosition.X, MapPosition.Y - 20), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale, SpriteEffects.None, 0f);
                //If the Map rebounds to far, it will adjust back to .Y = 50.
                if (MapPosition.Y < 50)
                {
                    MapPosition.Y = 50;
                }
                //The deposit textures will gimmick the map via the same draw
                //method looping from an array.
                for (int i = 0; i < depositPos.Length; i++)
                {
                    spriteBatch.Draw(dotTexture, depositPos[i] = new Vector2(depositPos[i].X, depositPos[i].Y - 20), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale / 1.5f, SpriteEffects.None, 0f);
                }
            }

            if (MapPosition.X > 80 && isDragging == false)
            {
                spriteBatch.Draw(Map, MapPosition = new Vector2(MapPosition.X - 20, MapPosition.Y), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale, SpriteEffects.None, 0f);
                if (MapPosition.X < 80)
                {
                    MapPosition.X = 80;
                }
                for (int i = 0; i < depositPos.Length; i++)
                {
                    spriteBatch.Draw(dotTexture, depositPos[i] = new Vector2(depositPos[i].X - 20, depositPos[i].Y), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale / 1.5f, SpriteEffects.None, 0f);
                }
                
            }
            if (480 - (Map.Height * mapScale) > MapPosition.Y && isDragging == false)
            {
                spriteBatch.Draw(Map, MapPosition = new Vector2(MapPosition.X, MapPosition.Y + 20), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale, SpriteEffects.None, 0f);
                if (MapPosition.Y > 480 - (Map.Height * mapScale))
                {
                    MapPosition.Y = 480 - (Map.Height * mapScale);
                }
                for (int i = 0; i < depositPos.Length; i++)
                {
                    spriteBatch.Draw(dotTexture, depositPos[i] = new Vector2(depositPos[i].X, depositPos[i].Y + 20), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale / 1.5f, SpriteEffects.None, 0f);
                }
                
            }
            if (800 - (Map.Width * mapScale) > MapPosition.X && isDragging == false)
            {
                spriteBatch.Draw(Map, MapPosition = new Vector2(MapPosition.X + 20, MapPosition.Y), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale, SpriteEffects.None, 0f);
                if (MapPosition.X > 800 - (Map.Height * mapScale))
                {
                    MapPosition.X = 800 - (Map.Height * mapScale);
                }
                for (int i = 0; i < depositPos.Length; i++)
                {
                    spriteBatch.Draw(dotTexture, depositPos[i] = new Vector2(depositPos[i].X + 20, depositPos[i].Y), null, Microsoft.Xna.Framework.Color.White, 0f, Vector2.Zero, mapScale / 1.5f, SpriteEffects.None, 0f);
                }
                
            }
        }
        #endregion

        public void MapRestrictions(float vectorPosX, float vectorPosY)
        {
            if (vectorPosY > 0 || vectorPosX > 0)
            {
                if (MapPosition.X > vectorPosX)
                {
                    MapPosition.X = vectorPosX;
                }

                if (MapPosition.Y > vectorPosY)
                {
                    MapPosition.Y = vectorPosY;
                }
            }
            else
            {
                if (MapPosition.X < vectorPosX)
                {
                    MapPosition.X = vectorPosX;
                }
                if (MapPosition.Y < vectorPosY)
                {
                    MapPosition.Y = vectorPosY;
                }
            }
        }



        public void ZoomOut()
        {
            if (mapScale > .51f)
            {
                MapPosition.X += 72f / 2;
                MapPosition.Y += 43f / 2;

                if (MapPosition.X >= 80)
                {
                    MapPosition.X = 80;
                }
                if (MapPosition.Y >= 50)
                {
                    MapPosition.Y = 50;
                }

                if (MapPosition.X < -Map.Width * mapScale + 850)
                {
                    MapPosition.X = 850 - (Map.Width*mapScale);
                }
                if (MapPosition.Y < -Map.Height * mapScale + 500)
                {
                    MapPosition.Y = 500 - (Map.Height*mapScale);
                }


                mapScale -= .05f;
            }
        }

        public void ZoomIn()
        {
             if (mapScale < 2f)
             {
                 MapPosition.X -= 72f / 2;
                 MapPosition.Y -= 43f / 2;

             }
            mapScale += .05f;
        }

        public void HandleTouch()
        {
            if (canMove)
            {
                TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.DragComplete | GestureType.Flick | GestureType.Hold;
                while (TouchPanel.IsGestureAvailable)
                {
                    GestureSample gesture = TouchPanel.ReadGesture();

                    if (gesture.GestureType == GestureType.FreeDrag)
                    {
                        velocity = Vector2.Zero;
                        MapPosition += gesture.Delta;

                        for (int i = 0; i < depositPos.Length; i++)
                        {
                            depositPos[i] += gesture.Delta;
                        }

                        isDragging = true;
                    }

                    if (gesture.GestureType == GestureType.DragComplete)
                    {
                        isDragging = false;

                    }

                    if (gesture.GestureType == GestureType.Flick)
                    {
                        velocity = Vector2.Zero;
                        velocity = gesture.Delta;

                    }

                    if (gesture.GestureType == GestureType.Hold)
                    {
                        velocity = Vector2.Zero;
                    }
                }
            }
        }
    }
}
